﻿/**********************************************************
 ●项目：Smartkernel
 ●公司：智能核心信息技术研发中心
 ●作者：曹艳白
 ●邮箱：caoyanbai@gmail.com
 ●创建：2008-08-10
**********************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Smartkernel.Extensions;

namespace Smartkernel.Net
{
    /// <summary>
    /// Ftp客户端类
    /// </summary>
    public static partial class SmartFtpClient
    {
        #region 直接操作
        /// <summary>
        /// 上传文件到Ftp服务器的指定目录
        /// </summary>
        /// <param name="ftpServer">Ftp服务器，例如：211.66.4.102</param>
        /// <param name="port">端口</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="localFilePath">本地文件路径</param>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="targetFileName">目标文件名</param>
        public static void Upload(string ftpServer, string port, string userName, string password, string ftpFolder, string localFilePath, string targetFileName)
        {
            FtpWebRequest ftpWebRequest;
            StringBuilder targetPath = new StringBuilder();
            targetPath.Append("ftp://" + ftpServer.Replace("ftp://", "") + ":" + port + "/");
            if (!ftpFolder.IsNullOrEmptyOrBlank())
            {
                targetPath.Append(ftpFolder + "/");
            }
            targetPath.Append(targetFileName);

            Uri uri = new Uri(targetPath.ToString());

            ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(uri);
            ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile;
            ftpWebRequest.UseBinary = true;
            ftpWebRequest.KeepAlive = false;
            ftpWebRequest.Credentials = new NetworkCredential(userName, password);

            using (Stream ftpStream = ftpWebRequest.GetRequestStream())
            {
                using (FileStream fileStream = new FileStream(localFilePath, FileMode.Open))
                {
                    int bufferSize = 2048 * 3;
                    byte[] buffer = new byte[bufferSize];
                    long length = fileStream.Length;
                    int pos = 0;
                    while (pos < length)
                    {
                        buffer = new byte[bufferSize];
                        int offSet = fileStream.Read(buffer, 0, bufferSize);
                        ftpStream.Write(buffer, 0, offSet);
                        pos += offSet;
                    }
                }
            }
        }
        /// <summary>
        /// 获得Ftp服务器指定目录的文件列表
        /// </summary>
        /// <param name="ftpServer">Ftp服务器，例如：211.66.4.102</param>
        /// <param name="port">端口</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <returns>文件列表</returns>
        public static List<string> GetFileList(string ftpServer, string port, string userName, string password, string ftpFolder)
        {
            List<string> list = new List<string>();
            StringBuilder targetFolder = new StringBuilder();
            targetFolder.Append("ftp://" + ftpServer.Replace("ftp://", "") + ":" + port + "/");
            if (!ftpFolder.IsNullOrEmptyOrBlank())
            {
                targetFolder.Append(ftpFolder + "/");
            }
            FtpWebRequest ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(targetFolder.ToString()));
            ftpWebRequest.Method = WebRequestMethods.Ftp.ListDirectory;
            ftpWebRequest.UseBinary = true;
            ftpWebRequest.Credentials = new NetworkCredential(userName, password);
            StringBuilder filePaths = new StringBuilder();
            using (WebResponse webResponse = ftpWebRequest.GetResponse())
            {
                try
                {
                    using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
                    {
                        string line = streamReader.ReadLine();
                        while (line != null)
                        {
                            filePaths.Append(line);
                            filePaths.Append("\n");
                            line = streamReader.ReadLine();
                        }
                    }
                }
                catch (Exception)
                { }
            }
            if (filePaths.Length > 0)
            {
                filePaths.Remove(filePaths.ToString().LastIndexOf('\n'), 1);
                list.AddRange(filePaths.ToString().Split('\n'));
            }
            return list;
        }
        /// <summary>
        /// 判断指定目录中是否存在指定的文件，不区分大小写
        /// </summary>
        /// <param name="ftpServer">Ftp服务器，例如：211.66.4.102</param>
        /// <param name="port">端口</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="targetFileName">目标文件名</param>
        /// <returns>是否存在</returns>
        public static bool Exists(string ftpServer, string port, string userName, string password, string ftpFolder, string targetFileName)
        {
            List<string> list = GetFileList(ftpServer, port, userName, password, ftpFolder);
            var linq = from file in list where file.ToLower().Trim() == targetFileName.ToLower().Trim() select file;
            return linq.Count() > 0;
        }
        /// <summary>
        /// 删除指定目录中的指定文件
        /// </summary>
        /// <param name="ftpServer">Ftp服务器，例如：211.66.4.102</param>
        /// <param name="port">端口</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="ftpFileNameList">要删除的文件列表</param>
        public static void Delete(string ftpServer, string port, string userName, string password, string ftpFolder, List<string> ftpFileNameList)
        {
            foreach (string fileName in ftpFileNameList)
            {
                if (Exists(ftpServer, port, userName, password, ftpFolder, fileName))
                {
                    StringBuilder targetFilePath = new StringBuilder();
                    targetFilePath.Append("ftp://" + ftpServer.Replace("ftp://", "") + ":" + port + "/");
                    if (!ftpFolder.IsNullOrEmptyOrBlank())
                    {
                        targetFilePath.Append(ftpFolder + "/");
                    }
                    targetFilePath.Append(fileName);
                    FtpWebRequest ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(targetFilePath.ToString()));
                    ftpWebRequest.Method = WebRequestMethods.Ftp.DeleteFile;
                    ftpWebRequest.UseBinary = true;
                    ftpWebRequest.Credentials = new NetworkCredential(userName, password);
                    using (FtpWebResponse ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse())
                    {
                        long size = ftpWebResponse.ContentLength;
                        using (Stream datastream = ftpWebResponse.GetResponseStream())
                        {
                            using (StreamReader streamReader = new StreamReader(datastream))
                            {
                                streamReader.ReadToEnd();
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 从指定Ftp服务器目录下载指定文件
        /// </summary>
        /// <param name="ftpServer">Ftp服务器，例如：211.66.4.102</param>
        /// <param name="port">端口</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="localFilePath">本地保存路径</param>
        /// <param name="targetFileName">目标文件名</param>
        public static void Download(string ftpServer, string port, string userName, string password, string ftpFolder, string localFilePath, string targetFileName)
        {
            StringBuilder targetFile = new StringBuilder();
            targetFile.Append("ftp://" + ftpServer.Replace("ftp://", "") + ":" + port + "/");
            if (!ftpFolder.IsNullOrEmptyOrBlank())
            {
                targetFile.Append(ftpFolder.TrimStart('/') + "/");
            }
            targetFile.Append(targetFileName.TrimStart('/'));
            FtpWebRequest ftpWebRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(targetFile.ToString()));
            ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile;
            ftpWebRequest.UseBinary = true;
            ftpWebRequest.Credentials = new NetworkCredential(userName, password);
            using (FtpWebResponse ftpWebResponse = (FtpWebResponse)ftpWebRequest.GetResponse())
            {
                using (Stream ftpStream = ftpWebResponse.GetResponseStream())
                {
                    long contentLength = ftpWebResponse.ContentLength;
                    int bufferSize = 2048;
                    byte[] buffer = new byte[bufferSize];
                    int readCount = ftpStream.Read(buffer, 0, bufferSize);
                    using (FileStream outputStream = new FileStream(localFilePath, FileMode.Create))
                    {
                        while (readCount > 0)
                        {
                            outputStream.Write(buffer, 0, readCount);
                            readCount = ftpStream.Read(buffer, 0, bufferSize);
                        }
                    }
                }
            }
        }
        #endregion
    }
    public static partial class SmartFtpClient
    {
        #region 通过配置文件初始化的实体
        /// <summary>
        /// 上传文件到Ftp服务器的指定目录，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="localFilePath">本地文件路径</param>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="targetFileName">目标文件名</param>
        public static void Upload(string ftpFolder, string localFilePath, string targetFileName)
        {
            Upload(SmartFtpClientEntity.Instance, ftpFolder, localFilePath, targetFileName);
        }
        /// <summary>
        /// 获得Ftp服务器指定目录的文件列表，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <returns>文件列表</returns>
        public static List<string> GetFileList(string ftpFolder)
        {
            return GetFileList(SmartFtpClientEntity.Instance, ftpFolder);
        }
        /// <summary>
        /// 判断指定目录中是否存在指定的文件，不区分大小写，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="targetFileName">目标文件名</param>
        /// <returns>是否存在</returns>
        public static bool Exists(string ftpFolder, string targetFileName)
        {
            return Exists(SmartFtpClientEntity.Instance, ftpFolder, targetFileName);
        }
        /// <summary>
        /// 删除指定目录中的指定文件，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="ftpFileNameList">要删除的文件列表</param>
        public static void Delete(string ftpFolder, List<string> ftpFileNameList)
        {
            Delete(SmartFtpClientEntity.Instance, ftpFolder, ftpFileNameList);
        }
        /// <summary>
        /// 从指定Ftp服务器目录下载指定文件，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="localFilePath">本地保存路径</param>
        /// <param name="targetFileName">目标文件名</param>
        public static void Download(string ftpFolder, string localFilePath, string targetFileName)
        {
            Download(SmartFtpClientEntity.Instance, ftpFolder, localFilePath, targetFileName);
        }
        #endregion
    }
    public static partial class SmartFtpClient
    {
        #region 直接通过配置实体
        /// <summary>
        /// 上传文件到Ftp服务器的指定目录，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="localFilePath">本地文件路径</param>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="targetFileName">目标文件名</param>
        /// <param name="entity">配置实体</param>
        public static void Upload(SmartFtpClientEntity entity, string ftpFolder, string localFilePath, string targetFileName)
        {
            Upload(entity.FtpServer, entity.Port, entity.UserName, entity.Password, ftpFolder, localFilePath, targetFileName);
        }
        /// <summary>
        /// 获得Ftp服务器指定目录的文件列表，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="entity">配置实体</param>
        /// <returns>文件列表</returns>
        public static List<string> GetFileList(SmartFtpClientEntity entity, string ftpFolder)
        {
            return GetFileList(entity.FtpServer, entity.Port, entity.UserName, entity.Password, ftpFolder);
        }
        /// <summary>
        /// 判断指定目录中是否存在指定的文件，不区分大小写，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="targetFileName">目标文件名</param>
        /// <param name="entity">配置实体</param>
        /// <returns>是否存在</returns>
        public static bool Exists(SmartFtpClientEntity entity, string ftpFolder, string targetFileName)
        {
            return Exists(entity.FtpServer, entity.Port, entity.UserName, entity.Password, ftpFolder, targetFileName);
        }
        /// <summary>
        /// 删除指定目录中的指定文件，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="ftpFileNameList">要删除的文件列表</param>
        /// <param name="entity">配置实体</param>
        public static void Delete(SmartFtpClientEntity entity, string ftpFolder, List<string> ftpFileNameList)
        {
            Delete(entity.FtpServer, entity.Port, entity.UserName, entity.Password, ftpFolder, ftpFileNameList);
        }
        /// <summary>
        /// 从指定Ftp服务器目录下载指定文件，配置文件SmartFtpClientEntity.config必须存在
        /// </summary>
        /// <param name="ftpFolder">Ftp服务器目录</param>
        /// <param name="localFilePath">本地保存路径</param>
        /// <param name="targetFileName">目标文件名</param>
        /// <param name="entity">配置实体</param>
        public static void Download(SmartFtpClientEntity entity, string ftpFolder, string localFilePath, string targetFileName)
        {
            Download(entity.FtpServer, entity.Port, entity.UserName, entity.Password, ftpFolder, localFilePath, targetFileName);
        }
        #endregion
    }
}
